home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / lib / calc / mod.cal < prev    next >
Text File  |  1995-07-17  |  3KB  |  212 lines

  1. /*
  2.  * Copyright (c) 1993 David I. Bell
  3.  * Permission is granted to use, distribute, or modify this source,
  4.  * provided that this copyright notice remains intact.
  5.  *
  6.  * Routines to handle numbers modulo a specified number.
  7.  *    a (mod N)
  8.  */
  9.  
  10. obj mod {a};            /* definition of the object */
  11.  
  12. global mod_value = 100;        /* modulus value (value of N) */
  13.  
  14.  
  15. define mod(a)
  16. {
  17.     local obj mod    x;
  18.  
  19.     if (!isreal(a) || !isint(a))
  20.         quit "Bad argument for mod function";
  21.     x.a = a % mod_value;
  22.     return x;
  23. }
  24.  
  25.  
  26. define mod_print(a)
  27. {
  28.     if (digits(mod_value) <= 20)
  29.         print a.a, "(mod", mod_value : ")" :;
  30.     else
  31.         print a.a, "(mod N)" :;
  32. }
  33.  
  34.  
  35. define mod_one()
  36. {
  37.     return mod(1);
  38. }
  39.  
  40.  
  41. define mod_cmp(a, b)
  42. {
  43.     if (isnum(a))
  44.         return (a % mod_value) != b.a;
  45.     if (isnum(b))
  46.         return (b % mod_value) != a.a;
  47.     return a.a != b.a;
  48. }
  49.  
  50.  
  51. define mod_rel(a, b)
  52. {
  53.     if (isnum(a))
  54.         a = mod(a);
  55.     if (isnum(b))
  56.         b = mod(b);
  57.     if (a.a < b.a)
  58.         return -1;
  59.     return a.a != b.a;
  60. }
  61.  
  62.  
  63. define mod_add(a, b)
  64. {
  65.     local obj mod    x;
  66.  
  67.     if (isnum(b)) {
  68.         if (!isint(b))
  69.             quit "Adding non-integer";
  70.         x.a = (a.a + b) % mod_value;
  71.         return x;
  72.     }
  73.     if (isnum(a)) {
  74.         if (!isint(a))
  75.             quit "Adding non-integer";
  76.         x.a = (a + b.a) % mod_value;
  77.         return x;
  78.     }
  79.     x.a = (a.a + b.a) % mod_value;
  80.     return x;
  81. }
  82.  
  83.  
  84. define mod_sub(a, b)
  85. {
  86.     return a + (-b);
  87. }
  88.  
  89.  
  90. define mod_neg(a)
  91. {
  92.     local obj mod    x;
  93.  
  94.     x.a = mod_value - a.a;
  95.     return x;
  96. }
  97.  
  98.  
  99. define mod_mul(a, b)
  100. {
  101.     local obj mod    x;
  102.  
  103.     if (isnum(b)) {
  104.         if (!isint(b))
  105.             quit "Multiplying by non-integer";
  106.         x.a = (a.a * b) % mod_value;
  107.         return x;
  108.     }
  109.     if (isnum(a)) {
  110.         if (!isint(a))
  111.             quit "Multiplying by non-integer";
  112.         x.a = (a * b.a) % mod_value;
  113.         return x;
  114.     }
  115.     x.a = (a.a * b.a) % mod_value;
  116.     return x;
  117. }
  118.  
  119.  
  120. define mod_square(a)
  121. {
  122.     local obj mod    x;
  123.  
  124.     x.a = a.a^2 % mod_value;
  125.     return x;
  126. }
  127.  
  128.  
  129. define mod_inc(a)
  130. {
  131.     local x;
  132.  
  133.     x = a;
  134.     if (++x.a == mod_value)
  135.         x.a = 0;
  136.     return x;
  137. }
  138.  
  139.  
  140. define mod_dec(a)
  141. {
  142.     local x;
  143.  
  144.     x = a;
  145.     if (--x.a < 0)
  146.         x.a = mod_value - 1;
  147.     return x;
  148. }
  149.  
  150.  
  151. define mod_inv(a)
  152. {
  153.     local obj mod    x;
  154.  
  155.     x.a = minv(a.a, mod_value);
  156.     return x;
  157. }
  158.  
  159.  
  160. define mod_div(a, b)
  161. {
  162.     local c, x, y;
  163.  
  164.     obj mod x, y;
  165.     if (isnum(a))
  166.         a = mod(a);
  167.     if (isnum(b))
  168.         b = mod(b);
  169.     c = gcd(a.a, b.a);
  170.     x.a = a.a / c;
  171.     y.a = b.a / c;
  172.     return x * inverse(y);
  173. }
  174.  
  175.  
  176. define mod_pow(a, b)
  177. {
  178.     local x, y, z;
  179.  
  180.     obj mod x;
  181.     y = a;
  182.     z = b;
  183.     if (b < 0) {
  184.         y = inverse(a);
  185.         z = -b;
  186.     }
  187.     x.a = pmod(y.a, z, mod_value);
  188.     return x;
  189. }
  190.  
  191.  
  192. global lib_debug;
  193. if (lib_debug >= 0) {
  194.     print "obj mod {a} defined";
  195.     print "mod(a) defined";
  196.     print "mod_print(a) defined";
  197.     print "mod_one(a) defined";
  198.     print "mod_cmp(a, b) defined";
  199.     print "mod_rel(a, b) defined";
  200.     print "mod_add(a, b) defined";
  201.     print "mod_sub(a, b) defined";
  202.     print "mod_mod(a, b) defined";
  203.     print "mod_square(a) defined";
  204.     print "mod_inc(a) defined";
  205.     print "mod_dec(a) defined";
  206.     print "mod_inv(a) defined";
  207.     print "mod_div(a, b) defined";
  208.     print "mod_pow(a, b) defined";
  209.     print "mod_value defined";
  210.     print "set mod_value as needed";
  211. }
  212.